/*=========================================================================
 Copyright (c) 2008, Nokia Corporation and/or its subsidiary(-ies).
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
 
     * Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
     * Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.
     * Neither the name of the Nokia Corporation and/or its subsidiary(-ies)nor the
       names of its contributors may be used to endorse or promote products
       derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=========================================================================================*/

#ifndef NCVOPTICALFLOW_H
#define NCVOPTICALFLOW_H

#include <e32base.h>
#include "ncvEgoMovement.h"

/**
 * \class COpticalFlow
 * \brief The optical flow class: motion estimations for each pixel.
 * This class also implements methods for calculating higher level information
 * from the optical flow
 *
 *
 */

class COpticalFlow : public CBase
	{
public:
	/**
	 * \brief Factory method for creating an instance.
	 * \param aImageSize Size of the optical flow map.
	 * \note aImageSize must be the size of the image used to deduce the optical flow.
	 * \note the function can leave
	 * \return COpticalFlow*
	 */
	IMPORT_C static COpticalFlow* NewL(const TSize& aImageSize);

	/**
	 * \brief Destructor.
	 */
	IMPORT_C virtual ~COpticalFlow();

	/**
	 * \brief Indexing operator.
	 * \param aX X coordinate.
	 * \param aY Y coordinate.
	 * \return Movement of the corresponding coordinates.
	 */
	IMPORT_C CEgoMovement& operator()(const TInt aX, const TInt aY);

	/**
	 * \brief Calculate the mean value of the optical flow. Represents tilting and panning of the camera
	 * (i.e. rotation around x and y axis).
	 * \return Mean movement of the optical flow.
	 */
	IMPORT_C CEgoMovement Mean() const;

	/**
	 * \brief Calculate the mean rotation of the optical flow around z axis.
	 * \note The return value is not in degrees. It has to be experimentally calibrated for different purposes.
	 * \return Rotation weight number.
	 */
	IMPORT_C CFixed Rotation();

	/**
	 * \brief Calculates movement along z-axis.
	 * \note The return value is not in pixels. It has to be experimentally calibrated for different purposes.
	 * \return Depth weight number.
	 */
	IMPORT_C CFixed Depth();

	/**
	 * \brief Reset the optical flow map.
	 */
	IMPORT_C void Reset();

	#ifndef NDEBUG
	/**
	 * \brief Debugging info about the optical flow map size.
	 * \note Only used in __ASSERT_DEBUGs.
	 * \return Size of the optical flow map.
	 */
	const TSize& Size()
		{
		return iFlowMapSize;
		}
	#endif /* NDEBUG */

protected:
	/**
	 * \brief Set runtime parameters of the Camus motion estimation algorithm.
	 * \param aCamusOpts Runtime parameters of the Camus algorithm.
	 */
	void SetCamusOpts(const TInt aCamusOpts);

private:

	/**
	 * \brief Constructor.
	 * \see NewL(const TSize& aImageSize) for parameters.
	 */
	COpticalFlow(const TSize& aFlowMapSize);

	/**
	 * \brief Second-phase constructor.
	 */
	void ConstructL();

	/**
	 * \brief Calculate the scale factor. This is the number of pixels included in statistical values.
	 * \note Returns KMaxTInt if there are zero used objects to avoid division by zero.
	 * \return Number of used CEgoMovement objects in the instance.
	 */
	TInt ScaleFactor() const;

	/// Optical flow map size.
	const TSize iFlowMapSize;

	/// Optical flow map.
	CEgoMovement* iFlowMap;

	/// Rotation template.
	CEgoMovement* iRotationTemplate;

	/// Depth template.
	CEgoMovement* iDepthTemplate;

	/// Camus options used in calculation.
	TInt iCamusOpts;
	friend class CCamus;
	};
#endif /* NCVOPTICALFLOW_H */
